﻿Public Class FMain
    Implements Framework.Log.ILogProvider

    Private Class ImageKeys
        Public Const BuddyOnline As String = "bu"
        Public Const BuddyOffline As String = "bo"
    End Class

    Private Sub FMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        Using clsMessage As New Framework.Message("Shutting down...")
            Host.Stop(clsMessage)
            Framework.Net.Manager.Stop(clsMessage)
            SetupEvents(False)
            Framework.Threading.MainGuiForm = Nothing
        End Using
    End Sub

    Private Sub SetupEvents(ByVal startListening As Boolean)
        'traces
        If startListening Then
            AddHandler Framework.Net.Manager.NetworkTraceInfo, AddressOf EventHandler_NetworkTraceInfo
            AddHandler Framework.Data.Environment.DBTraceInfo, AddressOf EventHandler_DBTraceInfo
            AddHandler FileShare.Engine.Manager.FileSysWatcherTrace, AddressOf EventHandler_FileSysWatcherTrace
        Else
            RemoveHandler Framework.Net.Manager.NetworkTraceInfo, AddressOf EventHandler_NetworkTraceInfo
            RemoveHandler Framework.Data.Environment.DBTraceInfo, AddressOf EventHandler_DBTraceInfo
            RemoveHandler FileShare.Engine.Manager.FileSysWatcherTrace, AddressOf EventHandler_FileSysWatcherTrace
        End If

        'misc
        If startListening Then
            AddHandler Framework.Net.Manager.NodeStatusChangedGUI, AddressOf EventHandler_NodeStatusChanged
            AddHandler Framework.Buddies.Manager.UpdatedGUI, AddressOf EventHandler_BuddyUpdated
            AddHandler Framework.Buddies.Manager.DeletedGUI, AddressOf EventHandler_BuddyDeleted
            AddHandler Framework.Net.Manager.SettingsChanged, AddressOf EventHandler_SettingsChangedNetNode
        Else
            RemoveHandler Framework.Net.Manager.NodeStatusChangedGUI, AddressOf EventHandler_NodeStatusChanged
            RemoveHandler Framework.Buddies.Manager.UpdatedGUI, AddressOf EventHandler_BuddyUpdated
            RemoveHandler Framework.Buddies.Manager.DeletedGUI, AddressOf EventHandler_BuddyDeleted
            RemoveHandler Framework.Net.Manager.SettingsChanged, AddressOf EventHandler_SettingsChangedNetNode
        End If
    End Sub

    Private Sub SetTitle()
        Me.Text = String.Format("{0} - {1}:{2} - B2B", Framework.Net.Settings.Nickname, Framework.Net.Settings.Host, Framework.Net.Settings.Port)
    End Sub

    Private Sub FMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        SetTitle()
        Me.Icon = Framework.My.Resources.Buddy

        ilBuddies.Images.Add(ImageKeys.BuddyOnline, Framework.My.Resources.Buddy_Online)
        ilBuddies.Images.Add(ImageKeys.BuddyOffline, Framework.My.Resources.Buddy_Offline)

        lvwBuddies.BeginUpdate()
        For Each clsBuddy As Entities.Buddy In Framework.Buddies.Manager.GetAll
            UpdateBuddyItem(clsBuddy)
        Next
        lvwBuddies.EndUpdate()

        SetupEvents(True)


        Dim strAppVersion As String
        If System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed Then
            strAppVersion = System.Deployment.Application.ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString()
        Else
            strAppVersion = Application.ProductVersion
        End If

        tslVersionInfo.Text = String.Format("Version {0} (app) {1} (db)", strAppVersion, Framework.Data.MetaData.GetDBVersion(Framework.Data.Source.Local).ToString)

        chkActive.Checked = Framework.Data.Environment.TraceStatements
    End Sub


    Private Sub EventHandler_BuddyUpdated(ByVal buddy As Entities.Buddy)
        Try
            UpdateBuddyItem(buddy)
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub
    Private Sub EventHandler_BuddyDeleted(ByVal buddy As Entities.Buddy)
        Try
            For Each clsItem As ListViewItem In lvwBuddies.Items
                Dim clsBud As Entities.Buddy = CType(clsItem.Tag, Entities.Buddy)
                If clsBud.Id = buddy.Id Then
                    clsItem.Remove()
                    Exit For
                End If
            Next
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub UpdateBuddyItem(ByVal buddy As Entities.Buddy)
        If buddy Is Nothing Then Return
        Dim strKey As String = buddy.Id.ToString
        Dim clsItem As ListViewItem
        If lvwBuddies.Items.ContainsKey(strKey) Then
            clsItem = lvwBuddies.Items(strKey)
        Else
            clsItem = lvwBuddies.Items.Add(strKey, String.Empty, CStr(Nothing))
        End If

        While clsItem.SubItems.Count < 3
            clsItem.SubItems.Add(String.Empty)
        End While
        clsItem.Text = buddy.NameLocal
        clsItem.SubItems(1).Text = Framework.Net.Manager.GetBuddyStatusText(buddy)
        clsItem.SubItems(2).Text = buddy.Comment
        If Framework.Net.Manager.IsBuddyOnline(buddy) Then
            clsItem.ImageKey = ImageKeys.BuddyOnline
        Else
            clsItem.ImageKey = ImageKeys.BuddyOffline
        End If
        clsItem.Tag = buddy
    End Sub

    Private Sub EventHandler_NodeStatusChanged(ByVal node As Framework.Net.Node)
        Try
            UpdateBuddyItem(node.Buddy)
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub
    Private Sub EventHandler_NodeDisonnected(ByVal node As Framework.Net.Node)
        Try
            UpdateBuddyItem(node.Buddy)
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub EventHandler_NetworkTraceInfo(ByVal e As Framework.Net.Manager.NetworkDataPackage)
        Try
            lvwNetworkTraffic.BeginUpdate()

            With lvwNetworkTraffic.Items.Insert(0, Now.ToString("HH:mm:ss.fff"))
                .SubItems.Add(e.Node.Name)
                If e.Direction = Framework.Net.Manager.NetworkDataPackage.PackageDirection.Information Then
                    .SubItems.Add(String.Empty)
                    .SubItems.Add(String.Empty)
                    .SubItems.Add(e.TextData.Replace(vbNewLine, String.Empty))
                Else
                    Dim strCode As String
                    If e.Direction = Framework.Net.Manager.NetworkDataPackage.PackageDirection.Incoming Then
                        strCode = e.Code & "<-"
                    Else
                        strCode = "->" & e.Code
                    End If
                    .SubItems.Add(strCode)
                    .SubItems.Add(e.Len.ToString)
                    If e.TextData IsNot Nothing Then
                        .SubItems.Add(e.TextData)
                    ElseIf e.RawData IsNot Nothing Then
                        If e.Len > 32 Then
                            Dim clsSB As New System.Text.StringBuilder
                            clsSB.Append(Framework.Misc.ToHexString(e.RawData, 0, 16, True))
                            clsSB.Append("...")
                            clsSB.Append(Framework.Misc.ToHexString(e.RawData, e.RawData.Length - 16, 16, True))
                            .SubItems.Add(clsSB.ToString)
                        Else
                            .SubItems.Add(Framework.Misc.ToHexString(e.RawData, True))
                        End If
                    Else
                        .SubItems.Add("[NOT SUPPLIED]")
                    End If
                End If
                .Tag = e
            End With
            While lvwNetworkTraffic.Items.Count > 100
                lvwNetworkTraffic.Items.RemoveAt(lvwNetworkTraffic.Items.Count - 1)
            End While

            lvwNetworkTraffic.EndUpdate()

        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub
    Private Sub EventHandler_DBTraceInfo(ByVal e As Framework.Data.Environment.TraceInfo)
        Try
            lvwSQLCETrace.BeginUpdate()
            With lvwSQLCETrace.Items.Insert(0, e.Timestamp.ToString("HH:mm:ss.fff"))
                .SubItems.Add(e.Thread)
                .SubItems.Add(e.Transaction)
                .SubItems.Add(e.Connection)
                .SubItems.Add(e.Statement)
                .Tag = e
            End With

            While lvwSQLCETrace.Items.Count > 300
                lvwSQLCETrace.Items.RemoveAt(lvwSQLCETrace.Items.Count - 1)
            End While
            lvwSQLCETrace.EndUpdate()
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub IssueConnectPinCodeToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles IssueConnectPinCodeToolStripMenuItem.Click
        If Framework.Net.Settings.Listen Then
            Dim clsView As New FIssueNewPairUpTicket
            clsView.Show(Me)
        Else
            MessageBox.Show(Me, "You can only issue pair up tickets if your node is setup to be public and listen to incoming connections!", "Pair Up Ticket", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
        End If
    End Sub

    Private Sub ViewActiveTicketsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ViewActiveTicketsToolStripMenuItem.Click
        Dim clsView As New FViewActivePairUpTickets
        clsView.Show(Me)
    End Sub

    Private Sub EnterPairUpTicketToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles EnterPairUpTicketToolStripMenuItem.Click
        Dim clsView As New FEnterPairUpTicket
        clsView.Show(Me)
    End Sub

    Private Sub lvwLog_MouseDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles lvwLog.MouseDoubleClick
        If lvwLog.SelectedItems.Count = 1 Then
            Dim clsTag As Object = lvwLog.SelectedItems(0).Tag
            If TypeOf clsTag Is Exception Then
                Dim ex As Exception = CType(clsTag, Exception)
                Dim sText As String = String.Format("{0}{1}{1}{2}", ex.Message, Environment.NewLine, ex.StackTrace)
                MessageBox.Show(Me, sText, "Exception details", MessageBoxButtons.OK, MessageBoxIcon.Information)
            End If
        End If
    End Sub

    Private Sub DeleteBuddyToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeleteBuddyToolStripMenuItem.Click
        Dim sText As String = Nothing
        Dim aBuds As New Generic.List(Of Entities.Buddy)
        Select Case lvwBuddies.SelectedItems.Count
            Case 0
                Return
            Case 1
                Dim clsBud As Entities.Buddy = CType(lvwBuddies.SelectedItems(0).Tag, Entities.Buddy)
                aBuds.Add(clsBud)
                sText = String.Format("Are you sure you want to delete the buddy {0}?", clsBud.NameLocal)
            Case Is > 1
                Dim clsSB As New System.Text.StringBuilder
                For i As Integer = 0 To lvwBuddies.SelectedItems.Count - 1
                    Dim clsBud As Entities.Buddy = CType(lvwBuddies.SelectedItems(i).Tag, Entities.Buddy)
                    If i = lvwBuddies.SelectedItems.Count - 1 Then
                        clsSB.Append(", and ")
                    ElseIf i > 0 Then
                        clsSB.Append(", ")
                    End If
                    clsSB.Append(clsBud.NameLocal)
                    aBuds.Add(clsBud)
                Next
                sText = String.Format("Are you sure you want to delete the {0} selected buddies {1}?", lvwBuddies.SelectedItems.Count, clsSB.ToString)
        End Select

        Select Case MessageBox.Show(Me, sText, "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2)
            Case Windows.Forms.DialogResult.Yes
            Case Else
                Return
        End Select

        For Each clsBud As Entities.Buddy In aBuds
            Framework.Buddies.Manager.Delete(clsBud)
        Next
    End Sub

    Private Sub ConnectBuddy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConnectBuddy.Click
        For Each clsItem As ListViewItem In lvwBuddies.SelectedItems
            Dim clsBud As Entities.Buddy = CType(clsItem.Tag, Entities.Buddy)
            Framework.Net.Manager.StartConnect(clsBud, False)
        Next
    End Sub

    Private Sub DisconnectBuddy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DisconnectBuddy.Click
        For Each clsItem As ListViewItem In lvwBuddies.SelectedItems
            Dim clsBud As Entities.Buddy = CType(clsItem.Tag, Entities.Buddy)
            Framework.Net.Manager.Disconnect(clsBud)
        Next
    End Sub

    Private Sub SettingsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SettingsToolStripMenuItem.Click
        Framework.Settings.Provider.Show(Me)
    End Sub

    Private Sub lvwNetworkTraffic_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lvwNetworkTraffic.DoubleClick
        If lvwNetworkTraffic.SelectedItems.Count = 1 Then
            Framework.Net.Manager.ViewNetworkPackage(Me, CType(lvwNetworkTraffic.SelectedItems(0).Tag, Framework.Net.Manager.NetworkDataPackage))
        End If
    End Sub

    Private Sub lvwBuddies_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lvwBuddies.DoubleClick
        ConnectBuddy_Click(sender, e)
    End Sub

    Private Sub EventHandler_SettingsChangedNetNode()
        Try
            SetTitle()
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub tmrUpdateDatarate_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrUpdateDatarate.Tick
        Try
            Dim iUploadRate As Integer = Framework.Net.Manager.GetCurrentUploadDataRate
            Dim iDownloadRate As Integer = Framework.Net.Manager.GetCurrentDownloadDataRate
            tslDatarate.Text = String.Format("Datarate: Up {0}  Down {1}", Framework.Misc.ToReadableSpeed(iUploadRate), Framework.Misc.ToReadableSpeed(iDownloadRate))
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub lvwSQLCETrace_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles lvwSQLCETrace.DoubleClick
        Try
            If lvwSQLCETrace.SelectedItems.Count = 1 Then
                Dim clsE As Framework.Data.Environment.TraceInfo = CType(lvwSQLCETrace.SelectedItems(0).Tag, Framework.Data.Environment.TraceInfo)
                MessageBox.Show(Me, clsE.Statement, String.Format("{0} {1}", clsE.Timestamp, clsE.Thread))
            End If
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub btnCopyDBTraceToClipboard_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCopyDBTraceToClipboard.Click
        Try
            Dim clsSB As New System.Text.StringBuilder
            For Each clsCol As ColumnHeader In lvwSQLCETrace.Columns
                clsSB.Append(clsCol.Text)
                clsSB.Append(vbTab)
            Next
            clsSB.AppendLine()
            For Each clsItem As ListViewItem In lvwSQLCETrace.Items
                For Each clsSI As ListViewItem.ListViewSubItem In clsItem.SubItems
                    clsSB.Append(clsSI.Text)
                    clsSB.Append(vbTab)
                Next
                clsSB.AppendLine()
            Next
            Clipboard.Clear()
            Clipboard.SetText(clsSB.ToString)
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try

    End Sub

    Private Sub chkActive_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkActive.CheckedChanged
        Try
            Framework.Data.Environment.TraceStatements = chkActive.Checked
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub BuddyPropertiesToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BuddyPropertiesToolStripMenuItem.Click
        Try
            Select Case lvwBuddies.SelectedItems.Count
                Case 0
                    Return
                Case Is >= 1
                    Dim clsBud As Entities.Buddy = CType(lvwBuddies.SelectedItems(0).Tag, Entities.Buddy)
                    Framework.Buddies.Manager.EditBuddy(Me, clsBud)
            End Select
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub ManageSecurityGroupsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ManageSecurityGroupsToolStripMenuItem.Click
        Try
            Framework.Security.Manager.ManageGroups(Me)
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private Sub EventHandler_FileSysWatcherTrace(ByVal watcher As String, ByVal [event] As String, ByVal path As String, ByVal ignored As Boolean)
        Try
            lvwFileSysWatchLog.BeginUpdate()
            With lvwFileSysWatchLog.Items.Insert(0, Now.ToString("HH:mm:ss.fff"))
                .SubItems.Add(watcher)
                .SubItems.Add([event])
                .SubItems.Add(CStr(IIf(ignored, "Yes", "No")))
                .SubItems.Add(path)
            End With

            While lvwFileSysWatchLog.Items.Count > 300
                lvwFileSysWatchLog.Items.RemoveAt(lvwFileSysWatchLog.Items.Count - 1)
            End While
            lvwFileSysWatchLog.EndUpdate()
        Catch ex As Exception
            Framework.Misc.HandleException(Me, ex)
        End Try
    End Sub

    Private mTabs As New Generic.Dictionary(Of String, TabPage)
    Friend Sub AddTab(ByVal tabKey As String, ByVal imageKey As String, ByVal caption As String, ByVal userControl As System.Windows.Forms.UserControl)
        Dim clsTP As New TabPage(caption)
        mTabs.Add(tabKey, clsTP)
        clsTP.Controls.Add(userControl)
        userControl.Dock = DockStyle.Fill
        tcPlugs.TabPages.Insert(0, clsTP)
        If imageKey IsNot Nothing Then clsTP.ImageKey = imageKey
    End Sub
    Friend Sub AddTabImage(ByVal imageKey As String, ByVal image As System.Drawing.Image)
        ilMainTabs.Images.Add(imageKey, image)
    End Sub
    Friend Sub ShowTab(ByVal tabKey As String)
        tcPlugs.SelectedTab = mTabs(tabKey)
    End Sub
    Friend Sub SetTabCaption(ByVal tabKey As String, ByVal caption As String)
        mTabs(tabKey).Text = caption
    End Sub
    Friend Sub SetTabImage(ByVal tabKey As String, ByVal imageKey As String)
        mTabs(tabKey).ImageKey = imageKey
    End Sub

    Public Sub LogError(ByVal text As String) Implements Framework.Log.ILogProvider.LogError
        AddLogItemEx(2, text, Nothing)
    End Sub
    Public Sub LogError(ByVal text As String, ByVal exception As System.Exception) Implements Framework.Log.ILogProvider.LogError
        AddLogItemEx(2, text, exception)
    End Sub
    Public Sub LogInformation(ByVal text As String) Implements Framework.Log.ILogProvider.LogInformation
        AddLogItemEx(0, text, Nothing)
    End Sub
    Public Sub LogWarning(ByVal text As String) Implements Framework.Log.ILogProvider.LogWarning
        AddLogItemEx(1, text, Nothing)
    End Sub
    Private Sub AddLogItemEx(ByVal imageIndex As Integer, ByVal text As String, ByVal exception As Exception)
        If Me.InvokeRequired Then
            Dim clsD As New Action(Of Integer, String, Exception)(AddressOf AddLogItemEx)
            Me.BeginInvoke(clsD, imageIndex, text, exception)
            Return
        End If

        lvwLog.BeginUpdate()
        With lvwLog.Items.Add(Now.ToString("HH:mm:ss.fff") & ": " & text)
            .Tag = exception
            .ImageIndex = imageIndex
        End With
        lvwLog.EnsureVisible(lvwLog.Items.Count - 1)
        While lvwLog.Items.Count > 300
            lvwLog.Items.RemoveAt(0)
        End While
        lvwLog.EndUpdate()
    End Sub

    Friend Sub AddPlugInMenu(ByVal menu As System.Windows.Forms.ToolStripMenuItem)
        MenuStrip1.Items.Add(menu)
    End Sub

End Class
